import ftplib
from os import path

from rftp import RFtp
from util import *


def dict2lines(d: dict) -> []:
    lines = []
    for (k, v) in d.items():
        lines.append(str(k) + ' ' + str(v) + '\n')
    return lines


class RCfg:
    RELEASE_FTP_FW_DIR_LIST_ELECOM = [
        '/switch/Projects/Elecom/Firmware/',
    ]
    RELEASE_FTP_FW_DIR_LIST_ME = [
        '/switch/Projects/D-Link/Sunflower/Firmware',
        '/v1/Project/Switch/DLINK-ME/Firmware'
    ]
    RELEASE_FTP_FW_BACKUP_DIR_LIST_ME = [
        '/switch/Projects/D-Link/Sunflower/Firmware/backup',
        '/v1/Project/Switch/DLINK-ME/Firmware/backup'
    ]

    def __init__(self, *args, **kwargs):
        self._cfg = None
        self._var = {
            'rls_models_dir_list': '~/release',
            'local_rls_store': '~/release/firmwares',
            'local_rls_note_store': '~/release/releasenotes',
            'ftp_host': '172.22.102.202',
            'ftp_user': '109965_wangqiang',
            'ftp_passwd': 'qw8Nmedd',
            'releaser': 'Wang Qiang',
            'log_dir': '~/release/logs',
            'release_ftp_fw_dir_list_me': ','.join(RCfg.RELEASE_FTP_FW_DIR_LIST_ME),
            'release_ftp_fw_backup_dir_list_me': ','.join(RCfg.RELEASE_FTP_FW_BACKUP_DIR_LIST_ME),
            'release_ftp_fw_dir_list_elecom': ','.join(RCfg.RELEASE_FTP_FW_DIR_LIST_ELECOM),
        }

    @property
    def release_ftp_fw_dir_list_elecom(self) -> []:
        return self._var['release_ftp_fw_dir_list_elecom'].split(',')

    @property
    def release_ftp_fw_dir_list_me(self) -> []:
        return self._var['release_ftp_fw_dir_list_me'].split(',')

    @property
    def release_ftp_fw_backup_dir_list_me(self) -> []:
        return self._var['release_ftp_fw_backup_dir_list_me'].split(',')

    def load(self, cfg_path: str):
        self._cfg = path_abs(cfg_path)
        if not Path(self._cfg).is_file():
            print(f'Config file ({self._cfg}) not exists!')
            exit()
        with open(self._cfg, 'r') as f:
            lines = f.readlines()
            for line in lines:
                li = line.split()
                if len(li) > 1 and li[0] in self._var:
                    self._var[li[0]] = ' '.join(li[1:])
        return self

    def cfg_chk(self):
        print('Config checking ...')

        def _cmn_chk(s, k):
            if not (isinstance(s, str) and not s.isspace()):
                print(f'Invalid value of {k}'
                      f'(empty or not a str): {d}')
                exit()

        def _dir_chk(p):
            if Path(path.expanduser(p)).is_dir() is False:
                print(f'Invalid directory: {p}')
                exit()

        for d in self.rls_models_dir_list:
            _cmn_chk(d, 'release model directory')
            _dir_chk(d)

        _dir_chk(self.local_rls_store)
        _dir_chk(self.local_rls_note_store)

        try:
            print('Ftp checking ...')
            ftp = RFtp(self.ftp_host, timeout=6)
            ftp.login(self.ftp_user, self.ftp_passwd)
        except TimeoutError as timeout:
            print(f"Connection timeout: {timeout}")
            print(f"Please check your network connection to host: {self.ftp_host}")
            exit()
        except ftplib.error_perm as err_perm:
            print(f"Login failed: {err_perm}")
            print(f"Username/Password wrong, please check your config file({self._cfg})")
            exit()

    def update(self, d: dict = None, w: bool = False):
        if d:
            self._var.update(d)
        if w:
            with open(self._cfg, 'w') as f:
                f.writelines(dict2lines(self._var))

    def dump(self) -> {}:
        return self._var

    @property
    def rls_models_dir_list(self) -> []:
        return [path_abs(p) for p in
                split_ex(self._var['rls_models_dir_list'], ',')]

    @property
    def local_rls_store(self) -> str:
        return path_abs(self._var['local_rls_store'])

    @property
    def local_rls_note_store(self) -> str:
        return path_abs(self._var['local_rls_note_store'])

    @property
    def releaser(self) -> str:
        return self._var['releaser']

    @property
    def ftp_host(self) -> str:
        return self._var['ftp_host']

    @property
    def ftp_user(self) -> str:
        return self._var['ftp_user']

    @property
    def ftp_passwd(self) -> str:
        return self._var['ftp_passwd']

    @property
    def log_dir(self) -> str:
        return path_abs(self._var['log_dir'])


cfg = RCfg()
